#ifndef _H_MOVEPOOL
#define _H_MOVEPOOL

#include "constants.h"

#include <stdint.h>

#include <string>
#include <unordered_map>
#include <vector>

#include <iostream>

namespace sokoban{

enum EMoveElem
{
  M_U = 'U',
  M_D = 'D',
  M_L = 'L',
  M_R = 'R',
  M_NONE = ' '
};

// the key is WHERE the move is going
typedef std::unordered_map< T_POS, std::string > MoveMap ;

class CMovePool
{
  public:

    CMovePool() { moves = new MoveMap; }

    CMovePool( CMovePool const & other )
    { moves = new MoveMap( *( other.moves ) ); }

    ~CMovePool() { delete moves; }

    // try to insert a move going from "from" doing the move "move" :
    //  - final position will be "from+move"
    //  - path will be "path to from + move"
    // If the insertion is successfull, an iterator on the newly inserted
    // move is returned, otherwise moves->end() is returned.
    MoveMap::iterator Insert
    (
      T_POS     from,
      EMoveElem move,
      T_DIM     nBoardCol
    );

    MoveMap::const_iterator CanGoThere( T_POS there ) const;

    MoveMap::const_iterator End() const { return moves->end(); }

    // Return a vector containing the reachable positions (that is, the
    // different keys of the movemap without the associated path).
    // Mostly useful for debugging purpose only. (now used also in getMinimumReachablePos)
    std::vector< T_POS > ToVector() const;

  private:

    MoveMap * moves;
};

struct CBoxMove
{
  CBoxMove
  (
    MoveMap::const_iterator playerMove,
    uint8_t movedBoxIdx,
    T_POS finalBoxPos,
    T_POS finalPlayerPos,
    EMoveElem move
  ):
    directions( playerMove->second + std::string(1, move) ),
    movedBoxIdx( movedBoxIdx ),
    finalBoxPos( finalBoxPos ),
    finalPlayerPos( finalPlayerPos )
  {
  }

  std::string ToString() const
  {
    std::string result;

    for( unsigned int i = 1 ; i < directions.size() ; i++ )
    {
      result += directions[ i ];
      result += ' ';
    }

    return result;
  }

  std::string directions;

  uint8_t  movedBoxIdx;

  T_POS finalBoxPos;
  T_POS finalPlayerPos;
};

/* sokoban */ }
#endif
